﻿/**	@file		_lolix_supported.hpp
 *	@date		(2009-11-20 22:10:51)/(2014-11-24 14:58:19)
 *-----------------------------------------------------------------------------
 *	@version	1.0.4.8
 *	@author		Nick Shallery	(nicknide@gmail.com)
 *	@copyright	YOU HAVE ALL LEFT WITH THIS CODE WHILE YOU KEEP COMMENT IN EVERY COPY.
 *-----------------------------------------------------------------------------
**/

#if			!defined(__LOLIX__LOLIX_SUPPORTED__HPP__K_IN_G__)
#define		__LOLIX__LOLIX_SUPPORTED__HPP__K_IN_G__

//==============================================================================
//--------------------------------------------------------------------------

#if			!defined(__LOLIX__LOLI_X_MACRO__K_IN_G__)
	#include	"./lolix_macro.h"
#endif	//	!defined(__LOLIX__LOLI_X_MACRO__K_IN_G__)


namespace lolix{

namespace _help{
	template<typename _Ty>
	struct _identity
	{
		typedef _Ty	type;
	};
}

#if			LOLIX_CFG__SUPPORT_CPP_0X
/**
* \brief	得到类型的右值引用模型
* \tparam	右值的基础类型
* \arg	o	待转换的数据
* \return	返回转换后的右值
**/
template<typename _Ty>
LOLIX_INLINE_CALL _Ty&& forward(typename _help::_identity<_Ty>::type& o)
{
	return (_Ty&&)o;
}
#endif	//	LOLIX_CFG__SUPPORT_CPP_0X

/**
* \brief	移除类型中的引用
* \tparam	_Ty	待处理类型
**/
template<typename _Ty> struct remove_reference{typedef _Ty type;};
/**
* \brief	移除类型中的引用
* \tparam	_Ty 待处理类型
**/
template<typename _Ty> struct remove_reference<_Ty&>{typedef _Ty type;};


/**
* \brief	移除类型中的常量
* \tparam	_Type	待处理的类型
**/
template<typename _Type> struct remove_const {/**移除常量之后的定义**/typedef _Type type; };
/**
* \brief	移除类型中的常量
* \tparam	_Type	待处理的类型
**/
template<typename _Type> struct	remove_const < const _Type > {/**移除常量之后的定义**/typedef _Type type; };


/**
* \brief	移除类型中的指针
* \tparam	_Ty	待处理类型
**/
template<typename _Ty> struct remove_pointer{typedef _Ty type;};
/**
* \brief	移除类型中的指针
* \tparam	_Ty	待处理类型
**/
template<typename _Ty> struct remove_pointer<_Ty*>{typedef _Ty type;};

namespace _help
{
#if			LOLIX_CFG__SUPPORT_CPP_0X
	template<typename _Ty>
	LOLIX_INLINE_CALL void __swap(_Ty& tl, _Ty& tr, decltype(tl.swap) = 0)
	{
		tl.swap(tr);
	}
#endif	//	LOLIX_CFG__SUPPORT_CPP_0X

	template<typename _Tl, typename _Tr>
	LOLIX_INLINE_CALL void __swap(_Tl& tl, _Tr& tr, ...)
	{
#if			LOLIX_CFG__SUPPORT_CPP_0X
		_Tl tmp(::lolix::forward<_Tl>(tl));
		tl = ::lolix::forward<_Tr>(tr);
		tr = ::lolix::forward<_Tl>(tmp);
#else	//	LOLIX_CFG__SUPPORT_CPP_0X
		_Tl tmp(tl);
		tl = tr;
		tr = tmp;
#endif	//	LOLIX_CFG__SUPPORT_CPP_0X
	}
}

template<typename _Tl, typename _Tr>
LOLIX_INLINE_CALL void swap(_Tl& tl, _Tr& tr)
{
	_help::__swap(tl, tr, 0);
}


template<typename _Tl, typename _Tr>
LOLIX_INLINE_CALL void discard_copy(_Tl& l, _Tr& r)
{
#if			LOLIX_CFG__SUPPORT_CPP_0X
	l = ::lolix::forward<_Tr>(r);
#else	//	LOLIX_CFG__SUPPORT_CPP_0X
	l = r;
#endif	//	LOLIX_CFG__SUPPORT_CPP_0X
}

namespace _help{
template<typename _Ty, typename _To>
LOLIX_INLINE_CALL _Ty* address_of_(_Ty& o, const _To&)
{
	int& v = (int&)o;
	return (_Ty*)&v;
}

template<typename _Ty>
LOLIX_INLINE_CALL _Ty* address_of_(_Ty& o, _Ty*)
{
	return &o;
}
}

template<typename _Ty>
LOLIX_INLINE_CALL _Ty* address_of(_Ty& o)
{
	return _help::address_of_(o, &o);
}

}



//--------------------------------------------------------------------------
//==============================================================================

#endif	//	!defined(__LOLIX__LOLIX_SUPPORTED__HPP__K_IN_G__)
